<template>
  <base-container v-loading="submitLoading">
    <el-form
      ref="formRef"
      class="flex flex-wrap pb72px"
      :model="roleForm"
      :rules="roleRules"
      label-width="78px"
      label-position="right"
    >
      <base-card class="w-[calc(50%-16px)] pb6px mr16px" title="角色信息">
        <el-form-item label="角色名称" prop="roleName">
          <el-input placeholder="请输入角色名称" v-model="roleForm.roleName" />
        </el-form-item>
        <el-form-item label="角色描述" prop="roleDesc">
          <el-input type="textarea" :rows="4" placeholder="请输入角色描述" v-model="roleForm.roleDesc" />
        </el-form-item>
      </base-card>
      <base-card class="w50% pb24px" title="角色配置">
        <el-form-item class="login-auth" label="登录验证" prop="isMacCheck">
          <el-radio-group v-model="roleForm.isMacCheck">
            <el-radio :value="0">关闭</el-radio>
            <el-radio :value="1">开启</el-radio>
          </el-radio-group>
        </el-form-item>
        <div class="message-tip col">
          <span>关闭登录验证后，成员可在任何设备登录系统。</span>
          <span>1、维护成员授信MAC地址：确保成员常用设备已添加至授信列表。</span>
          <span>
            2、成员常用设备需安装登录校验设备
            <el-link class="ml2px" type="primary" underline="always">下载设备 </el-link>
          </span>
          <span>3、开启登录验证：完成地址维护后方可开启功能。</span>
        </div>
      </base-card>
      <base-card class="w100% mt16px pb6px" title="角色权限">
        <el-form-item class="reference-role w38% max-w450px" label="参考角色">
          <el-select v-model="curRole" placeholder="请选择参考角色" clearable @change="handleRoleChange">
            <el-option v-for="role in roleList" :key="role.id" :label="role.roleName" :value="role.id"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item class="func-permission" label="功能权限" prop="menuIds">
          <base-tree
            v-model="roleForm.menuIds"
            :data="treeData"
            node-key="id"
            actions-prop="actions"
            :props="treeProps"
            v-loading="treeLoading"
          >
            <template #empty>
              <div class="wfull h500px center">
                <base-empty :image-size="180" description="暂无权限数据" />
              </div>
            </template>
          </base-tree>
        </el-form-item>
      </base-card>
    </el-form>
    <!-- 底部按钮 -->
    <div class="form-btn center">
      <el-button @click="handleCancel">取消</el-button>
      <el-button type="primary" :disabled="submitLoading" :loading="submitLoading" @click="loadSubmitRoleInfo">
        保存
      </el-button>
    </div>
  </base-container>
</template>

<script setup>
  // 获取路由实例
  const router = useRouter();

  onMounted(() => {
    // 获取菜单树数据
    loadGetMenuRoleTree();
    // 获取角色数据
    loadGetRoleList();
  });

  // 表单组件实例
  const formRef = ref({});

  // 角色表单
  const roleForm = ref({
    roleName: "", // 角色名称
    roleDesc: "", // 角色描述
    isMacCheck: 0, // 登录验证 0-关闭 1-开启
    menuTree: [], // 菜单树
    menuIds: [], // 菜单权限
  });

  // 角色校验规则
  const roleRules = {
    roleName: [
      { required: true, message: "请输入角色名称", trigger: "blur" },
      { min: 1, max: 20, message: "角色名称必须在 1-20 个字符内", trigger: "blur" },
    ],
    roleDesc: [
      { required: true, message: "请输入角色描述", trigger: "blur" },
      { min: 1, max: 50, message: "角色描述必须在 1-50 个字符内", trigger: "blur" },
    ],
    isMacCheck: [{ required: true }],
  };

  // 菜单树数据
  const treeData = ref([]);

  // 树形属性
  const treeProps = {
    children: "children",
    label: "name",
  };

  // 菜单树加载状态
  const treeLoading = ref(false);

  // 获取菜单树数据
  const loadGetMenuRoleTree = () => {
    return new Promise((resolve, reject) => {
      // 开始加载
      treeLoading.value = true;
      // 运管菜单树
      Api.menu
        .GetMenuRoleTree({ platform: 1 })
        .then(res => {
          treeData.value = filterMenuTree(res.data || []);
          resolve();
        })
        .catch(reject)
        .finally(() => (treeLoading.value = false));
    });
  };

  // 过滤菜单，将 category 为 4 的节点挂载到最近的父节点上
  const filterMenuTree = nodes => {
    if (!nodes || !nodes.length) return [];

    // 将树形结构平铺为一维数组
    const flattenTree = (nodes = []) => {
      return nodes.flatMap(node => {
        // 递归获取子节点
        if (!node.children || node.children.length === 0) return [node];
        // 有子节点，继续递归
        return [node, ...flattenTree(node.children)];
      });
    };

    // 递归处理节点
    return nodes.map(node => {
      const newNode = { ...node };

      // 如果没有子节点，直接返回
      if (!newNode.children || newNode.children.length === 0) return newNode;

      const actions = [];
      const regularChildren = [];

      // 遍历子节点，将 category 为 4 的节点收集到 actions 数组中
      newNode.children.forEach(child => {
        // 处理 category === 4
        if (child.category === 4) {
          // 如果子节点是 action，收集它和它的所有后代
          actions.push(child);
          if (child.children && child.children.length > 0) {
            actions.push(...flattenTree(child.children));
          }
        } else {
          // 如果是普通菜单，放入待递归列表
          regularChildren.push(child);
        }
      });

      // 将收集到的 actions 挂载到当前节点
      if (actions.length > 0) {
        newNode.actions = actions;
      }

      // 对普通子节点进行递归处理
      newNode.children = filterMenuTree(regularChildren);

      // 处理完毕，返回新节点
      return newNode;
    });
  };

  // 角色数据
  const roleList = ref([]);

  // 当前选择角色
  const curRole = ref("");

  // 获取角色列表
  const loadGetRoleList = () => {
    return new Promise((resolve, reject) => {
      Api.role
        .GetAllRoleList()
        .then(res => {
          roleList.value = res.data || [];
          resolve();
        })
        .catch(reject);
    });
  };

  // 参考角色选中变化
  const handleRoleChange = roleId => {
    // 如果情况下拉选择，取消所有已选
    if (!roleId) return (roleForm.value.menuIds = []);
    // 开始权限树加载
    treeLoading.value = true;
    // 获取指定角色菜单权限ID
    Api.role
      .GetRoleDetail({ id: roleId })
      .then(res => {
        const data = res.data || {};
        // 如果是超级管理员，全选所有权限点
        if (data.roleType === 1) {
          const traverseNodeId = nodes => {
            return nodes.reduce((ids, node) => {
              ids.push(node.id);
              if (node.children && node.children.length > 0) {
                ids = ids.concat(traverseNodeId(node.children));
              }
              // 如果有 actions，也添加进去
              if (node.actions && node.actions.length > 0) {
                node.actions.forEach(action => ids.push(action.id));
              }
              return ids;
            }, []);
          };
          data.menuIds = traverseNodeId(treeData.value);
        }
        // 设置菜单权限
        roleForm.value.menuIds = data.menuIds || [];
      })
      .finally(() => (treeLoading.value = false));
  };

  // 提交加载状态
  const submitLoading = ref(false);

  // 提交角色信息
  const loadSubmitRoleInfo = () => {
    formRef.value.validate(valid => {
      if (!valid) return;
      // 开始加载
      submitLoading.value = true;
      // 提交角色信息
      Api.role
        .AddRole(roleForm.value)
        .then(() => {
          // 消息提示
          $msg.success("新增成功");
          // 关闭当前页面，跳转到角色列表
          router.replace({ path: ROUTE_PATHS.ROLE.LIST });
        })
        .finally(() => {
          // 结束加载
          submitLoading.value = false;
        });
    });
  };

  // 取消按钮，返回上级页面
  const handleCancel = () => router.replace({ path: ROUTE_PATHS.ROLE.LIST });
</script>
<style lang="scss" scoped>
  // 引入角色样式
  @use "@/views/permission/style/role.scss";
</style>
